﻿using System;
using System.Collections.Generic;
using System.Text;

namespace X3DLib
{
    public class Grass : X3dInterfaceObject
    {
        //public Group globalGroup;//用于保存第二个Group，提高设置属性时的速度//不可行，修改数目无效

        /// <summary>
        /// 选择小草模型的序号（1或2）
        /// </summary>
        private int DemoIndex
        {
            get { return demoIndex; }
            set { demoIndex = value; }
        }

        private string leafNum;

        /// <summary>
        /// 叶子数目
        /// </summary>
        public string LeafNum
        {
            get { return leafNum; }
            set { leafNum = value; }
        }

        private string grassNum;
        /// <summary>
        /// 草棵数
        /// </summary>
        public string GrassNum
        {
            get { return grassNum; }
            set { grassNum = value; }
        }

        private string grassRadius;
        /// <summary>
        /// 草地的范围半径
        /// </summary>
        public string GrassRadius
        {
            get { return grassRadius; }
            set { grassRadius = value; }
        }

        private string profile;
        /// <summary>
        /// 草地的形状:square或者sphere
        /// </summary>
        public string Profile
        {
            get { return profile; }
            set { profile = value; }
        }

        private string control;
        /// <summary>
        /// 草地的生成方式：random或者round
        /// </summary>
        public string Control
        {
            get { return control; }
            set { control = value; }
        }

        private string color;
        /// <summary>
        /// 叶子颜色
        /// </summary>
        public string Color
        {
            get { return color; }
            set { color = value; }
        }

        private string leafRadius;
        /// <summary>
        /// 叶子的半径
        /// </summary>
        public string LeafRadius
        {
            get { return leafRadius; }
            set { leafRadius = value; }
        }
        private string leafScale;
        /// <summary>
        /// 叶子的形状
        /// </summary>
        public string LeafScale
        {
            get { return leafScale; }
            set { leafScale = value; }
        }
        private string leafAngle;
        /// <summary>
        /// 叶子与地面的角度
        /// </summary>
        public string LeafAngle
        {
            get { return leafAngle; }
            set { leafAngle = value; }
        }

        private int demoIndex = 1;//小草模型

        /// <summary>
        /// 构造函数
        /// </summary>
        public Grass()
        {
            this.demoIndex = 1;
            this.leafNum = "3";
            this.leafScale = "0.2 1.1 0.05";
            this.leafRadius = "0.2";
            this.leafAngle = "0.785";
            this.color = "0 1 0";
            this.grassRadius = "5";
            this.grassNum = "50";
            this.profile = "square";
            this.control = "random";


            int gnumber = Int32.Parse(this.grassNum);//草的数量转为整型
            //globalGroup = new Group();
            //globalGroup = setGroupArr(setTransArr());

            this.addChildren(setGroup());
            //this.addChildren(this.globalGroup);
            this.addChildren(setGroupArr(setTransArr()));
            //Transform[] tempTranArr = new Transform[gnumber];
            //tempTranArr = this.setTransArr();
            //for (int i = 0; i < gnumber; i++)
            //{
            //    this.addChildren(tempTranArr[i]);
            //}
        }

        //public Grass(int leafnum,float leafradius,float leafheight,string color,float radius,int grassnum,string profile,string control)
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="demoIndex">小草模型,eg:1</param>
        /// <param name="leafNum">叶子数目，eg:3</param>
        /// <param name="leafScale">叶子形状,eg:0.2 1.1 0.05</param>
        /// <param name="leafRadius">叶子半径,eg:0.2</param>
        /// <param name="leafAngle">叶子角度,eg:0.785</param>
        /// <param name="color">叶子颜色,eg:0 1 0</param>
        /// <param name="grassRadius">草地范围,eg:5</param>
        /// <param name="grassNum">草数目,eg:50</param>
        /// <param name="profile">草地形状,eg:square，round，halfround</param>
        /// <param name="control">生成方式,eg:random</param>        
        public Grass(int demoIndex, string leafNum, string leafScale, string leafRadius, string leafAngle, string color, string grassRadius, string grassNum, string profile, string control)
        {
            this.demoIndex = demoIndex;
            this.leafNum = leafNum;
            this.leafScale = leafScale;
            this.leafRadius = leafRadius;
            this.leafAngle = leafAngle;
            this.color = color;
            this.grassRadius = grassRadius;
            this.grassNum = grassNum;

            this.profile = profile;
            this.control = control;


            int gnumber = Int32.Parse(this.grassNum);
            //globalGroup = new Group();
            //globalGroup = setGroupArr(setTransArr());

            this.addChildren(setGroup());
            //this.addChildren(this.globalGroup);
            this.addChildren(setGroupArr(setTransArr()));
            //Transform[] tempTranArr = new Transform[gnumber];
            //tempTranArr = this.setTransArr();
            //for (int i = 0; i < gnumber; i++)
            //{
            //    this.addChildren(tempTranArr[i]);
            //}
        }

        public Group setGroup()
        {
            Group group = new Group();
            group.DEF = "grassdemo";
            Background background = new Background();
            background.skyColor = "0.239216 0.839216 1";
            background.groundColor = "0.5 0.4 0.3";
            group.addChildren(background);

            Shape tempShape1 = new Shape();

            #region 草地模型1
            if (this.demoIndex == 1)
            {
                int templeafnum = Int32.Parse(this.LeafNum);

                Transform transform = new Transform();
                transform.DEF = "L0";
                transform.scale = "0.2 1.1 0.05";
                transform.rotation = "1 0 0 0.785";
                transform.center = "0 -0.2 0";
                //第一片叶子
                Sphere sphere = new Sphere();
                sphere.radius = this.leafRadius;
                tempShape1.addChildren(sphere);

                Appearance app = new Appearance();
                app.material = new Material(this.color);
                tempShape1.addChildren(app);

                transform.addChildren(tempShape1);
                group.addChildren(transform);

                X3dScaleRandom scalerandom = new X3dScaleRandom(1.0f, 1.0f, 1.0f, templeafnum);
                string[] scaleArr = scalerandom.createScaleArr();

                float[] angles = new float[templeafnum];
                Transform[] tranArr = new Transform[templeafnum];
                //其他叶子
                for (int i = 0; i < templeafnum; i++)
                {
                    angles[i] = (float)(6.282 / templeafnum * (i + 1));
                    tranArr[i] = new Transform();
                    tranArr[i].scale = scaleArr[i];
                    tranArr[i].rotation = "0 1 0 " + angles[i].ToString();
                    tranArr[i].center = "0 -0.2 0";
                    tranArr[i].addChildren(new Shape("L0"));
                    group.addChildren(tranArr[i]);
                }
            }
            #endregion

            #region 草地模型2
            else if (this.demoIndex == 2)
            {
                int templeafnum = Int32.Parse(this.LeafNum);

                Transform transform = new Transform();
                transform.DEF = "L0";
                //transform.scale = "0.2 1.1 0.05";
                transform.rotation = "1 0 0 0.785";
                transform.center = "0 -0.2 0";
                //第一片叶子
                _Cone cone = new _Cone();
                cone.bottomRadius = this.leafRadius;
                cone.height = (double.Parse(this.leafRadius) * 40).ToString();
                tempShape1.addChildren(cone);

                Appearance app = new Appearance();
                app.material = new Material(this.color);
                tempShape1.addChildren(app);

                transform.addChildren(tempShape1);
                group.addChildren(transform);

                X3dScaleRandom scalerandom = new X3dScaleRandom(1.0f, 1.0f, 1.0f, templeafnum);
                string[] scaleArr = scalerandom.createScaleArr();

                float[] angles = new float[templeafnum];
                Transform[] tranArr = new Transform[templeafnum];
                //其他叶子
                for (int i = 0; i < templeafnum; i++)
                {
                    angles[i] = (float)(6.282 / templeafnum * (i + 1));
                    tranArr[i] = new Transform();
                    tranArr[i].scale = scaleArr[i];
                    tranArr[i].rotation = "0 1 0 " + angles[i].ToString();
                    tranArr[i].center = "0 -0.2 0";
                    tranArr[i].addChildren(new Shape("L0"));
                    group.addChildren(tranArr[i]);
                }


                //tempShape1.DEF = "L0";

                //_Cone cone = new _Cone();
                //cone.bottomRadius = this.leafRadius;//.ToString(); ;
                //cone.height = this.leafAngle;//.ToString();
                //tempShape1.addChildren(cone);

                //Appearance app = new Appearance();
                //app.material = new Material(this.color);
                //tempShape1.addChildren(app);
                //group.addChildren(tempShape1);

                //Transform[] tranArr = new Transform[3];
                //for (int i = 0; i < 3; i++)
                //{
                //    tranArr[i] = new Transform();
                //}
                //tranArr[0].rotation = "-0.5 1 0 -1.7";
                //tranArr[0].scale = "0.8 0.8 0.8";
                //tranArr[0].translation = "-0.4 -0.305 0.35";
                //tranArr[0].addChildren(new Shape("L0"));
                //group.addChildren(tranArr[0]);

                //tranArr[1].rotation = "0.5 1 0 1.7";
                //tranArr[1].scale = "0.9 0.9 0.9";
                //tranArr[1].translation = "0.42 -0.305 0.35";
                //tranArr[1].addChildren(new Shape("L0"));
                //group.addChildren(tranArr[1]);

                //tranArr[2].rotation = "0 1 -0.5 1.4";
                //tranArr[2].scale = "0.7 0.7 0.7";
                //tranArr[2].translation = "0.28 -0.36 -0.25";
                //tranArr[2].addChildren(new Shape("L0"));
                //group.addChildren(tranArr[2]);
            }
            #endregion
            #region 草地模型3
            else if (this.demoIndex == 3)
            {
                int templeafnum = Int32.Parse(this.LeafNum);

                Transform transform = new Transform();
                transform.DEF = "L0";
                transform.scale = "0.2 1.1 0.05";
                transform.rotation = "1 0 0 0.785";
                transform.center = "0 -0.2 0";
                //第一片叶子
                Sphere sphere = new Sphere();
                sphere.radius = this.leafRadius;
                tempShape1.addChildren(sphere);

                Appearance app = new Appearance();
                app.material = new Material(this.color);
                tempShape1.addChildren(app);

                transform.addChildren(tempShape1);
                group.addChildren(transform);

                X3dScaleRandom scalerandom = new X3dScaleRandom(1.0f, 1.0f, 1.0f, templeafnum);
                string[] scaleArr = scalerandom.createScaleArr();

                float[] angles = new float[templeafnum];
                Transform[] tranArr = new Transform[templeafnum];
                //其他叶子
                for (int i = 0; i < templeafnum; i++)
                {
                    angles[i] = (float)(6.282 / templeafnum * (i + 1));
                    tranArr[i] = new Transform();
                    tranArr[i].scale = scaleArr[i];
                    tranArr[i].rotation = "0 1 0 " + angles[i].ToString();
                    tranArr[i].center = "0 -0.2 0";
                    tranArr[i].addChildren(new Shape("L0"));
                    group.addChildren(tranArr[i]);
                }
                //小花
                Group flowerGroup = new Group();
                flowerGroup.DEF = "flower";

                Transform flowerBanch = new Transform();
                flowerBanch.center = "0 -0.2 0";

                Shape flowerBanchShape = new Shape();
                Appearance tempAppBanch = new Appearance();
                tempAppBanch.material = new Material("0.5 0.4 0.3");
                flowerBanchShape.appearance = tempAppBanch;

                IndexedLineSet lineset = new IndexedLineSet();
                lineset.coordIndex = "0 1";
                lineset.Coordinate = new Coordinate("0 -0.2 0 0 0.3 0");
                flowerBanchShape.geometry = lineset;

                flowerBanch.addChildren(flowerBanchShape);
                flowerGroup.addChildren(flowerBanch);

                Transform flowerLeafTran = new Transform();
                flowerLeafTran.translation = "0 0.5 0";

                Transform flowerLeaf = new Transform();
                flowerLeaf.DEF = "F0";
                flowerLeaf.rotation = "1 0 0 1.00";
                flowerLeaf.scale="0.2 0.3 0.05";
                flowerLeaf.center = "0 -0.2 0";

                Shape flowerLeafShape = new Shape();
                Appearance tempAppLeaf = new Appearance();
                tempAppLeaf.material = new Material("1 0 1");
                flowerLeafShape.appearance = tempAppLeaf;
                flowerLeafShape.geometry = new Sphere("0.2");
                
                flowerLeaf.addChildren(flowerLeafShape);
                flowerLeafTran.addChildren(flowerLeaf);

                float[] flowerAngles = new float[templeafnum];
                Transform[] flowerTranArr = new Transform[2];
                //其他叶子
                for (int i = 0; i < 2; i++)
                {
                    flowerAngles[i] = (float)(6.282 / 3 * (i + 1));
                    flowerTranArr[i] = new Transform();
                    flowerTranArr[i].rotation = "0 1 0 " + flowerAngles[i].ToString();
                    flowerTranArr[i].center = "0 -0.2 0";
                    flowerTranArr[i].addChildren(new Shape("F0"));
                    flowerLeafTran.addChildren(flowerTranArr[i]);
                }

                flowerGroup.addChildren(flowerLeafTran);
                group.addChildren(flowerGroup);

            }
            #endregion
            return group;
        }

        public Transform[] setTransArr()
        {
            int gnumber = Int32.Parse(this.grassNum);
            X3dArea x3darea = new X3dArea(this.profile, this.control, new double[] { 0.0f, 0.0f, 0.0f }, float.Parse(this.grassRadius), gnumber);
            //x3darea.Number = gnumber;
            //x3darea.Control = this.control;
            //x3darea.Profile = this.profile;

            X3dScaleRandom scalerandom = new X3dScaleRandom(1.0f, 1.0f, 1.0f, gnumber);
            string[] scaleArr = scalerandom.createScaleArr();

            string[] translationArr = x3darea.createTranslationArr();
            Transform[] transform = new Transform[gnumber];
            for (int i = 0; i < gnumber; i++)
            {
                transform[i] = new Transform();
                //transform[i].center = ;
                transform[i].scale = scaleArr[i];
                transform[i].translation = translationArr[i];
                transform[i].addChildren(new Group("grassdemo"));
            }
            return transform;
        }

        public Group setGroupArr(Transform[] tranArr)
        {
            Group group2 = new Group();
            for (int i = 0; i < tranArr.Length; i++)
            {
                group2.addChildren(tranArr[i]);
            }
            return group2;
        }

        public override string getAttrs()
        {
            return "demoIndex|" + this.demoIndex.ToString() + "|max:2 min:1,"
                    + "leafNum|" + this.leafNum + "|int32,"
                    + "leafScale|" + this.leafScale + "|float[3],"
                    + "leafRadius|" + this.leafRadius + "|float,"
                    + "leafAngle|" + this.leafAngle + "|float,"
                    + "color|" + this.color + "|max:1 min:0,"
                    + "grassRadius|" + this.grassRadius + "|float,"
                    + "grassNum|" + this.grassNum + "|int32,"
                    + "profile|" + this.profile + "|string,"
                    + "control|" + this.control + "|string";
        }

        public override void setAttrs(string attrs)
        {
            string[][] temp = X3DString.getArrayByAttrs(attrs);
            for (int i = 0; i < temp.Length; i++)
            {
                switch (temp[i][0])
                {
                    case "demoIndex":
                        this.demoIndex = Int32.Parse(temp[i][1]);
                        break;
                    case "leafNum":
                        this.leafNum = temp[i][1];
                        break;
                    case "leafScale":
                        this.leafScale = temp[i][1];
                        break;
                    case "leafRadius":
                        this.leafRadius = temp[i][1];
                        break;
                    case "leafAngle":
                        this.leafAngle = temp[i][1];
                        break;
                    case "grassNum":
                        this.grassNum = temp[i][1];
                        break;
                    case "grassRadius":
                        this.grassRadius = temp[i][1];
                        break;
                    case "profile":
                        this.profile = temp[i][1];
                        break;
                    case "control":
                        this.control = temp[i][1];
                        break;
                    case "color":
                        //System.Windows.Forms.MessageBox.Show("123");
                        this.color = temp[i][1];
                        break;
                }
            }
            setAttributes(this.demoIndex, this.leafNum, this.leafScale, this.leafRadius, this.leafAngle, this.color, this.grassRadius, this.grassNum, this.profile, this.control);

        }

        private void setAttributes(int demoIndex, string leafNum, string leafScale, string leafRadius, string leafAngle, string color, string grassRadius, string grassNum, string profile, string control)
        {
            this.demoIndex = demoIndex;
            this.leafNum = leafNum;
            this.leafScale = leafScale;
            this.leafRadius = leafRadius;
            this.leafAngle = leafAngle;
            this.color = color;
            this.grassRadius = grassRadius;
            this.grassNum = grassNum;
            this.profile = profile;
            this.control = control;

            //int count = this.children.Count;
            //for (int i = 0; i < this.children.Count; i++)
            //{
            //    this.removeChildren(i);
            //}
            this.clearChildren();
            //this.children.Clear();
            //while (this.children.Count > 0)
            //{
            //    this.children.RemoveAt(this.children.Count-1);
            //}
            //this.children.RemoveAll();
            int gnumber = Int32.Parse(this.grassNum);

            this.addChildren(setGroup());
            //this.addChildren(globalGroup);
            this.addChildren(setGroupArr(setTransArr()));
            //Transform[] tempTranArr = new Transform[gnumber];
            //tempTranArr = this.setTransArr();
            //for (int i = 0; i < gnumber; i++)
            //{
            //    this.addChildren(tempTranArr[i]);
            //}
            //System.Windows.Forms.MessageBox.Show("123");
        }

    }
}
